#include "mainGUI.h"

Node head, *top;

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
void win_show(Node *);

int x, y;

void addMessage(char *msg, bool isTop)
{
	Node *node;
	
	if (isTop)
		node = top;
	else
	{
		char myUID[LEN], uID[LEN];
		
		sscanf(msg, "%s %s", uID, myUID);
		for (node = head.nxt; node != &head; node = node->nxt)
			if (strcmp(node->head, uID) == 0)
				break;
		msg = msg + strlen(myUID) + strlen(uID) + 2;
	}
	
	strcpy(node->body[node->ed], msg);
	node->ed = (node->ed + 1) % (NLINES - 6);
	if (node->roll)
		node->st = (node->st + 1) % (NLINES - 6);
	if (node->ed == 0)
		node->roll = 1;
    
    if (node == top)
        win_show(top);
}

void win_show(Node *node)
{	int startx, starty, height, width;

	if (node == &head)
		return;
	
	getbegyx(node->w, starty, startx);
	getmaxyx(node->w, height, width);

	wclear(node->w);
	box(node->w, 0, 0);
	mvwaddch(node->w, 2, 0, ACS_LTEE); 
	mvwhline(node->w, 2, 1, ACS_HLINE, width - 2); 
	mvwaddch(node->w, 2, width - 1, ACS_RTEE); 
	
	mvwaddch(node->w, NLINES - 3, 0, ACS_LTEE); 
	mvwhline(node->w, NLINES - 3, 1, ACS_HLINE, width - 2); 
	mvwaddch(node->w, NLINES - 3, width - 1, ACS_RTEE); 
	
	int line = 3;
	int qh = node->st;
	for (line = 3; line < NLINES - 3; line++)
	{
		mvwprintw(node->w, line, 1, "%s", node->body[qh]);
		qh = (qh + 1) % (NLINES - 6);
	}
	mvwprintw(node->w, NLINES - 2, 1, "%s", node->msg);
	mvprintw(30, 2, "%s", node->head);
	
	print_in_middle(node->w, 1, 0, width, node->head, COLOR_PAIR(1));
	
	wmove(node->w, NLINES - 2, node->pos + 1);
}

void init_wins(char *uID)
{
	char label[80];
	
	Node *node = new Node();
	node->w = newwin(NLINES, NCOLS, y, x);
	keypad(node->w, TRUE);
	strcpy(node->head, uID);
	strcpy(node->msg, "");
	node->pos = 0;
	node->st = node->ed = node->roll = 0;
	win_show(node);
	y += 3;
	x += 7;
	
	node->p = new_panel(node->w);
	node->pre = top;
	node->nxt = top->nxt;
	top->nxt = node;
	top = node;
	
	top_panel(top->p);
	update_panels();
	doupdate();
}

void mainGUI(char *nickname[], char *uID[], int n_choices)
{	ITEM **my_items;
	int c;				
	MENU *my_menu;
	int i;
	
	initscr();
	start_color();
	cbreak();
	noecho();
	keypad(stdscr, TRUE);
	init_pair(1, COLOR_RED, COLOR_BLACK);
	init_pair(2, COLOR_CYAN, COLOR_BLACK);

	my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
	for(i = 0; i < n_choices; ++i)
		my_items[i] = new_item(nickname[i], uID[i]);
//	my_items[i++] = new_item("Exit", "");
//	my_items[i] = (ITEM *)NULL;
	n_choices--;

	my_menu = new_menu((ITEM **)my_items);

	head.w = newwin(10, 40, 4, 4);
	head.pre = head.nxt = &head;
	top = &head;
	keypad(head.w, TRUE);
	y = 2;
	x = 50;
     
	set_menu_win(my_menu, head.w);
	set_menu_sub(my_menu, derwin(head.w, 6, 38, 3, 1));
	set_menu_format(my_menu, 5, 1);
			
	set_menu_mark(my_menu, " * ");

	box(head.w, 0, 0);
	print_in_middle(head.w, 1, 0, 40, "My Menu", COLOR_PAIR(1));
	mvwaddch(head.w, 2, 0, ACS_LTEE);
	mvwhline(head.w, 2, 1, ACS_HLINE, 38);
	mvwaddch(head.w, 2, 39, ACS_RTEE);
        
	post_menu(my_menu);
	wrefresh(head.w);
	
	head.p = new_panel(head.w);
	update_panels();
	
	attron(COLOR_PAIR(2));
	mvprintw(LINES - 2, 0, "Use PageUp and PageDown to scoll down or up a page of items");
	mvprintw(LINES - 1, 0, "Arrow Keys to navigate (F1 to Exit)");
	attroff(COLOR_PAIR(2));
//	puts("****");
	refresh();
	
	int pos = 0;

//	puts("====");
	while((c = wgetch(top->w)) != KEY_F(1))
	{
		if (top == &head)
		{
			switch(c)
			{
				case KEY_DOWN:
					menu_driver(my_menu, REQ_DOWN_ITEM);
					if (pos < n_choices - 1)
						pos++;
					break;
				case KEY_UP:
					menu_driver(my_menu, REQ_UP_ITEM);
					if (pos > 0)
						pos--;
					break;
//				case KEY_NPAGE:
//					menu_driver(my_menu, REQ_SCR_DPAGE);
//					break;
//				case KEY_PPAGE:
//					menu_driver(my_menu, REQ_SCR_UPAGE);
//					break;
				case 343:
					init_wins(uID[pos]);
                    tellMessage(uID[pos]);
					break;
				case 9:
					top = top->nxt;
					top_panel(top->p);
					update_panels();
					doupdate();
					win_show(top);
					break;
			}
		}
		else
		{
			switch(c)
			{
				case 9:
					top = top->nxt;
					top_panel(top->p);
					update_panels();
					doupdate();
					break;
				case 343:
					addMessage(top->msg, 1);
                    sendMessage(top->head, top->msg);
					memset(top->msg, 0, sizeof(top->msg));
					top->pos = 0;
					win_show(top);
					break;
				case 127:
					if (top->pos > 0)
						top->msg[--top->pos] = 0;
					break;
				default:
					if (top->pos < NCOLS - 3)
						top->msg[top->pos++] = c;
			}
//			mvprintw(40, 1, "press %d msg = %s", c, top->msg);
			win_show(top);
		}
//		wrefresh(top->w);
	}

	unpost_menu(my_menu);
	free_menu(my_menu);
	for(i = 0; i < n_choices; ++i)
		free_item(my_items[i]);
	endwin();
}

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
{	int length, x, y;
	float temp;

	if(win == NULL)
		win = stdscr;
	getyx(win, y, x);
	if(startx != 0)
		x = startx;
	if(starty != 0)
		y = starty;
	if(width == 0)
		width = 80;

	length = strlen(string);
	temp = (width - length)/ 2;
	x = startx + (int)temp;
	wattron(win, color);
	mvwprintw(win, y, x, "%s", string);
	wattroff(win, color);
	refresh();
}
